package com.simen.hellobytes.encrypt;

import com.simen.hellobytes.exception.EncryptException;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.security.MessageDigest;

/**
 * @author Created by Simen.
 * @date 创建日期 2018/8/30 14:22
 * @modify 修改者 Simen
 */
public class SHAUtil {

    private static final String ALGORITHM_SHA1 = "SHA-1";
    private static final String ALGORITHM_SHA256 = "SHA-256";
    private static final String ALGORITHM_SHA512 = "SHA-512";

    public static byte[] getSha1(byte[] data) throws EncryptException {
        return digest(ALGORITHM_SHA1, data);
    }

    public static byte[] getSha256(byte[] data) throws EncryptException {
        return digest(ALGORITHM_SHA256, data);
    }

    public static byte[] getSha512(byte[] data) throws EncryptException {
        return digest(ALGORITHM_SHA512, data);
    }

    public static byte[] getFileSha1(File file) throws EncryptException {
        return digestFile(ALGORITHM_SHA1, file);
    }

    public static byte[] getFileSha256(File file) throws EncryptException {
        return digestFile(ALGORITHM_SHA256, file);
    }

    public static byte[] getFileSha512(File file) throws EncryptException {
        return digestFile(ALGORITHM_SHA512, file);
    }

    public static byte[] digest(String algorithm, byte[] data) throws EncryptException {
        try {
            MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
            messageDigest.update(data);
            return messageDigest.digest();
        } catch (Exception e) {
            throw new EncryptException(e);
        }
    }

    public static byte[] digestFile(String algorithm,File file) throws EncryptException{
        FileInputStream in = null;
        try {
            in = new FileInputStream(file);

            MappedByteBuffer byteBuffer = in.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, file.length());

            MessageDigest md5Digest = MessageDigest.getInstance(algorithm);
            md5Digest.update(byteBuffer);

            return md5Digest.digest();
        } catch (Exception e) {
            throw new EncryptException(e);
        } finally {
            if (null != in) {
                try {
                    in.close();
                } catch (IOException e) {
                }
            }
        }
    }


}
